#pragma	once

#include <winbase.h>

namespace	Z
{

//------------------------------------------------------------------------------------------------------------------------
class _ZMainApi	SlimReaderWriterLock
{
private:
	typedef	void(SlimReaderWriterLock::*Pfn)();
public:
	SlimReaderWriterLock()	{
		::InitializeSRWLock(&mSRWLock);
	}
	~SlimReaderWriterLock()	{
	}
	void	acquire(bool write)	{
		(this->*smAcquires[write])();
	}
	void	release(bool write)	{
		(this->*smReleases[write])();
	}
private:
	void	acquireExclusive()	{
		::AcquireSRWLockExclusive(&mSRWLock);
    }
	void	releaseExclusive()	{
		::ReleaseSRWLockExclusive(&mSRWLock);
    }
	void	acquireShared()	{
		::AcquireSRWLockShared(&mSRWLock);
    }
	void	releaseShared()	{
		::ReleaseSRWLockShared(&mSRWLock);
    }

private:
	SRWLOCK	mSRWLock;
	static	Pfn	smAcquires[];
	static	Pfn	smReleases[];

//------------------------------------------------------------------------------------------------------------------------
public:
	class	scoped_lock	{
	public:
		scoped_lock(SlimReaderWriterLock& slimReaderWriterLock, bool write = true)
			:	mSlimReaderWriterLock(slimReaderWriterLock),
				mWrite(write)	{
			mSlimReaderWriterLock.acquire(mWrite);
		}
		~scoped_lock()	{
			mSlimReaderWriterLock.release(mWrite);
		};
	private:
		SlimReaderWriterLock&	mSlimReaderWriterLock;
		bool	mWrite;
	};
};

}